package org.fjsei.yewu.job;

import com.alibaba.fastjson2.JSON;
import org.fjsei.yewu.repository.maint.SplJob;
import org.fjsei.yewu.repository.maint.SplJobRepository;
import org.quartz.InterruptableJob;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.quartz.JobKey;
import org.springframework.util.StringUtils;
import java.time.LocalDateTime;
import java.util.function.Function;
import static graphql.Assert.assertNotNull;

//【多通道】接口的分页查询模式的，可能不连续或重叠部分key，总页数可能变动的；分拆多个通道：分别负责一个范围的page
public interface PagenumJob extends InterruptableJob {
    public boolean isInterrupt();
    public boolean executeSlice(JobKey  jobKey,SplJob  splJob);
    public SplJobRepository splJobRepo();
    public void setSplJob(SplJob  splJob);
    public SplJob getSplJob();

    @Override
    public default void execute(JobExecutionContext context) throws JobExecutionException {
//        if(!emSei.isJoinedToTransaction())      emSei.joinTransaction();
//        Assert.isTrue(emSei.isJoinedToTransaction(),"没emFjtj Transaction");
        JobKey  jobKey = context.getJobDetail().getKey();
        SplJob  splJob= splJobRepo().findByGroupNameAndJobName(jobKey.getGroup(),jobKey.getName());
        setSplJob(splJob);
        try {
            for(long i=0; ; i++){
                if(isInterrupt() || context.getScheduler().isShutdown()){
                    System.out.println("Scheduler down break");
                    return;
                }
                if(!executeSlice(jobKey,getSplJob()))
                    break;
            }
        } catch (Exception e) {
            Thread.currentThread().interrupt();  // 恢复中断状态
            System.out.println("线程被中断...");
        } finally {
        }
    }

    //页数范围是拆分的事前确定数值。每一个page大小也是固定好的；
   public default boolean runSlice(SplJob  splJob, Function<Long, String> sliceJob,Boolean breakOnError)
   {
       Long  pnumCurr = null;
       if(StringUtils.hasText(splJob.getCurr())){
           pnumCurr= JSON.parseObject(splJob.getCurr(), Long.class);
       }
       Long pnumEnd = null;
       if(StringUtils.hasText(splJob.getEndr())){
           pnumEnd= JSON.parseObject(splJob.getEndr(), Long.class);
       }
       assertNotNull(pnumEnd, () -> "pnumEnd空");
       Long pnumStart = null;
       if(StringUtils.hasText(splJob.getStart())){
           pnumStart= JSON.parseObject(splJob.getStart(), Long.class);
       }
       //即将作业的页数
        Long parent=null!=pnumCurr?pnumCurr : (null==pnumStart? 1: pnumStart);
        if(parent<=pnumEnd){
            //粒度加粗到一个页大小的。而不是一行的。所以当中不能被中断！     if(isInterrupt()) break;
            try {
                sliceJob.apply(parent);         //单1页的
            } catch (Exception e) {
                e.printStackTrace();
                splJob.setResult(e.getMessage());
                splJob.setLast(LocalDateTime.now());
                //乐观锁方式，没采用强的事务一致保证；
                setSplJob(splJobRepo().save(splJob));
                if(breakOnError)  return false;    //让JOB被中止掉的；
                else return true;
            }
            parent++;
            String lastSort = JSON.toJSONString(parent);
            splJob.setCurr(lastSort);
            splJob.setOffs(splJob.getOffs() + 1);
        }
        splJob.setLast(LocalDateTime.now());
        if(parent>pnumEnd){
            splJob.setResult("任务正常完成！");
            setSplJob(splJobRepo().save(splJob));
            return false;
        }
        setSplJob(splJobRepo().save(splJob));
        return true;
    }
}
